/*
 * AscEmu Framework based on ArcEmu MMORPG Server
 * Copyright (c) 2014-2025 AscEmu Team <http://www.ascemu.org>
 * Copyright (C) 2008-2012 ArcEmu Team <http://www.ArcEmu.org/>
 * Copyright (C) 2005-2007 Ascent Team
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "Logging/Logger.hpp"
#include "Objects/Units/Players/PlayerClasses.hpp"
#include "Server/World.h"
#include "Spell/Definitions/SpellModifierType.hpp"
#include "Spell/Definitions/SpellDamageType.hpp"
#include "Spell/Definitions/CastInterruptFlags.hpp"
#include "Spell/Definitions/AuraInterruptFlags.hpp"
#include "Storage/WDB/WDBStores.hpp"
#include "Spell/Definitions/SpellRanged.hpp"
#include "Spell/Definitions/DispelType.hpp"
#include "Spell/Definitions/SpellMechanics.hpp"
#include "Spell/Definitions/SpellEffectTarget.hpp"
#include "Spell/SpellHelpers.h"
#include "Spell/SpellInfo.hpp"
#include "Spell/SpellMgr.hpp"
#include "Spell/SpellTarget.h"
#include "Spell/Definitions/SpellEffects.hpp"
#include "Storage/WDB/WDBStructures.hpp"

using AscEmu::World::Spell::Helpers::decimalToMask;

void SpellMgr::createDummySpell(uint32_t id)
{
    SpellInfo* sp = new SpellInfo;
    memset(sp, 0, sizeof(SpellInfo));
    sp->setId(id);
    sp->setAttributes(ATTRIBUTES_NO_CAST | ATTRIBUTES_NO_VISUAL_AURA); //384
    sp->setAttributesEx(ATTRIBUTESEX_UNK30);    //268435456
    sp->setAttributesExB(ATTRIBUTESEXB_IGNORE_LINE_OF_SIGHT);   //4
    sp->setCastingTimeIndex(1);
    sp->setProcChance(75);
    sp->setRangeIndex(13);
    sp->setEquippedItemClass(-1);
    sp->setEffect(SPELL_EFFECT_DUMMY, 0);
    sp->setEffectImplicitTargetA(EFF_TARGET_DUEL, 0);
    sp->setEffectDamageMultiplier(1.0f, 0);
    sWorld.dummySpellList.push_back(sp);
}

void SpellMgr::modifyEffectBasePoints(SpellInfo* sp)
{
    if (sp == nullptr)
    {
        sLogger.failure("Something tried to call with an invalid spell pointer!");
        return;
    }

    //Rogue: Poison time fix for 2.3
    if (sp->getId() == 3408)                 // Crippling Poison && Effect[0] == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
        sp->setEffectBasePoints(3599, 0);
    if (sp->getId() == 5761)                 // Mind-numbing Poison && Effect[0] == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
        sp->setEffectBasePoints(3599, 0);
    if (sp->getId() == 8679)                 // Instant Poison && Effect[0] == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
        sp->setEffectBasePoints(3599, 0);
    if (sp->getId() == 2823)                 // Deadly Poison && Effect[0] == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
        sp->setEffectBasePoints(3599, 0);
    if (sp->getId() == 13219)                // Wound Poison && Effect[0] == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
        sp->setEffectBasePoints(3599, 0);
    if (sp->getId() == 26785)                // Anesthetic Poison && Effect[0] == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
        sp->setEffectBasePoints(3599, 0);

    // Zyres: According to the description the weapon damage gets increased from 2 to 12 (depends on the different spell ids)
    if (sp->getId() == 2828 || sp->getId() == 29452 || sp->getId() == 29453 || sp->getId() == 56308) //Sharpen Blade && Effect[0] == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
        sp->setEffectBasePoints(3599, 0);

    // Set the diff. EffectBasePoint from description.
    if (sp->getId() == 11119)     // Ignite Rank 1
        sp->setEffectBasePoints(8, 0);
    if (sp->getId() == 11120)     // Ignite Rank 2
        sp->setEffectBasePoints(16, 0);
    if (sp->getId() == 12846)     // Ignite Rank 3
        sp->setEffectBasePoints(24, 0);
    if (sp->getId() == 12847)     // Ignite Rank 4
        sp->setEffectBasePoints(32, 0);
    if (sp->getId() == 12848)     // Ignite Rank 5
        sp->setEffectBasePoints(40, 0);
}

void SpellMgr::setMissingSpellLevel(SpellInfo* sp)
{
    if (sp == nullptr)
    {
        sLogger.failure("Something tried to call with an invalid spell pointer!");
        return;
    }

    //stupid spell ranking problem
    if (sp->getSpellLevel() == 0)
    {
        uint32 new_level = 0;

        // 16/03/08 Zyres: just replaced name assignes with spell ids. \todo remove not teachable spells.
        switch (sp->getId())
        {
            // name "Aprentice "
            case 2020:
            case 2155:
            case 2275:
            case 2372:
            case 2551:
            case 2581:
            case 3279:
            case 3911:
            case 4039:
            case 7414:
            case 7733:
            case 8615:
            case 25245:
            case 29535:
            case 33388:
            case 33389:
            case 45375:
            case 51216:
            {
                new_level = 1;
            } break;
            // name "Journeyman "
            case 2021:
            case 2154:
            case 2280:
            case 2373:
            case 2582:
            case 3280:
            case 3412:
            case 3912:
            case 4040:
            case 7415:
            case 7734:
            case 8619:
            case 25246:
            case 33391:
            case 33392:
            case 45376:
            case 64485:
            {
                new_level = 2;
            } break;
            // name "Expert "
            case 2552:
            case 3465:
            case 3539:
            case 3568:
            case 3571:
            case 3812:
            case 3913:
            case 4041:
            case 7416:
            case 7736:
            case 7925:
            case 8620:
            case 19886:
            case 19889:
            case 19903:
            case 28896:
            case 34090:
            case 34092:
            case 45377:
            case 54083:
            case 54254:
            case 54257:
            {
                new_level = 3;
            } break;
            // name "Artisan "
            case 9786:
            case 10249:
            case 10663:
            case 10769:
            case 10847:
            case 11612:
            case 11994:
            case 12181:
            case 12657:
            case 13921:
            case 18249:
            case 18261:
            case 19887:
            case 19890:
            case 19902:
            case 28899:
            case 34091:
            case 34093:
            case 45378:
            {
                new_level = 4;
            } break;
            // name "Master "
            case 12613:
            case 13958:
            case 13970:
            case 13971:
            case 14904:
            case 15024:
            case 15025:
            case 15026:
            case 15027:
            case 17039:
            case 17040:
            case 17041:
            case 18709:
            case 18710:
            case 18767:
            case 18768:
            case 19825:
            case 21935:
            case 21940:
            case 23759:
            case 23760:
            case 23761:
            case 23762:
            case 23784:
            case 23785:
            case 23822:
            case 23823:
            case 23824:
            case 23825:
            case 23826:
            case 23827:
            case 23828:
            case 23829:
            case 23830:
            case 23831:
            case 23832:
            case 23833:
            case 23834:
            case 23835:
            case 23836:
            case 23837:
            case 23838:
            case 23839:
            case 23840:
            case 23841:
            case 23842:
            case 23843:
            case 23844:
            case 24347:
            case 24626:
            case 24627:
            case 26791:
            case 27029:
            case 27235:
            case 27236:
            case 27237:
            case 28030:
            case 28597:
            case 28696:
            case 28901:
            case 29074:
            case 29075:
            case 29076:
            case 29077:
            case 29355:
            case 29460:
            case 29461:
            case 29845:
            case 30351:
            case 31221:
            case 31222:
            case 31223:
            case 31226:
            case 31227:
            case 31665:
            case 31666:
            case 32550:
            case 32679:
            case 33098:
            case 33100:
            case 33360:
            case 33361:
            case 33894:
            case 34130:
            case 34149:
            case 34150:
            case 34485:
            case 34486:
            case 34487:
            case 34488:
            case 34489:
            case 34506:
            case 34507:
            case 34508:
            case 34833:
            case 34834:
            case 34835:
            case 34836:
            case 34837:
            case 34838:
            case 34839:
            case 35702:
            case 35703:
            case 35704:
            case 35705:
            case 35706:
            case 35708:
            case 35874:
            case 35912:
            case 36001:
            case 38734:
            case 39097:
            case 39098:
            case 39099:
            case 40369:
            case 40385:
            case 40388:
            case 43784:
            case 44868:
            case 45379:
            case 45713:
            case 46417:
            case 46418:
            case 46444:
            case 47872:
            case 47873:
            case 47874:
            case 47875:
            case 47876:
            case 47877:
            case 48028:
            case 48411:
            case 48412:
            case 48418:
            case 48420:
            case 48421:
            case 48422:
            case 48729:
            case 48730:
            case 49776:
            case 52143:
            case 52559:
            case 53125:
            case 53662:
            case 53663:
            case 53664:
            case 53665:
            case 53666:
            case 54084:
            case 54255:
            case 54256:
            case 54721:
            case 55188:
            case 55434:
            case 55435:
            case 57853:
            case 58410:
            case 62698:
            case 65022:
            case 66409:
            case 66410:
            case 66417:
            case 66420:
            case 66423:
            case 66457:
            case 66460:
            case 66461:
            case 66677:
            case 66810:
            case 66812:
            case 67551:
            case 69716:
            case 70528:
            {
                new_level = 5;
            } break;
            // name "Grand Master "
            case 45380:
            case 50299:
            case 50301:
            case 50307:
            case 50309:
            case 51293:
            case 51295:
            case 51298:
            case 51301:
            case 51303:
            case 51305:
            case 51308:
            case 51310:
            case 51312:
            case 61464:
            case 64484:
            case 65281:
            case 65282:
            case 65283:
            case 65284:
            case 65285:
            case 65286:
            case 65287:
            case 65288:
            case 65289:
            case 65290:
            case 65291:
            case 65292:
            case 65293:
            {
                new_level = 6;
            } break;
            default:
                break;
        }

        if (new_level != 0)
        {
            uint32 teachspell = 0;
            if (sp->getEffect(0) == SPELL_EFFECT_LEARN_SPELL)
                teachspell = sp->getEffectTriggerSpell(0);
            else if (sp->getEffect(1) == SPELL_EFFECT_LEARN_SPELL)
                teachspell = sp->getEffectTriggerSpell(1);
            else if (sp->getEffect(2) == SPELL_EFFECT_LEARN_SPELL)
                teachspell = sp->getEffectTriggerSpell(2);

            if (teachspell)
            {
                const auto spellInfo = getMutableSpellInfo(teachspell);
                if (spellInfo != nullptr)
                {
                    spellInfo->setSpellLevel(new_level);
                    sp->setSpellLevel(new_level);
                }
            }
        }
    }
}

void SpellMgr::modifyAuraInterruptFlags(SpellInfo* sp)
{
    if (sp == nullptr)
    {
        sLogger.failure("Something tried to call with an invalid spell pointer!");
        return;
    }

    // HACK FIX: Break roots/fear on damage.. this needs to be fixed properly!
    if (!(sp->getAuraInterruptFlags() & AURA_INTERRUPT_ON_ANY_DAMAGE_TAKEN))
    {
        for (uint8 z = 0; z < 3; ++z)
        {
            if (sp->getEffectApplyAuraName(z) == SPELL_AURA_MOD_FEAR || sp->getEffectApplyAuraName(z) == SPELL_AURA_MOD_ROOT)
            {
                sp->addAuraInterruptFlags(AURA_INTERRUPT_ON_UNUSED2);
                break;
            }
        }
    }
}

void SpellMgr::modifyRecoveryTime(SpellInfo* sp)
{
    if (sp == nullptr)
    {
        sLogger.failure("Something tried to call with an invalid spell pointer!");
        return;
    }

    // Description includes
    switch (sp->getId())
    {
        // "Must remain seated" 154 rows o.O
        case 430:
        case 431:
        case 432:
        case 433:
        case 434:
        case 435:
        case 833:
        case 1127:
        case 1129:
        case 1131:
        case 1133:
        case 1135:
        case 1137:
        case 2639:
        case 5004:
        case 5005:
        case 5006:
        case 5007:
        case 7737:
        case 9177:
        case 10250:
        case 10256:
        case 10257:
        case 18071:
        case 18124:
        case 18140:
        case 18229:
        case 18230:
        case 18231:
        case 18232:
        case 18233:
        case 18234:
        case 21149:
        case 22731:
        case 22734:
        case 23540:
        case 23541:
        case 23542:
        case 23692:
        case 23698:
        case 24005:
        case 24355:
        case 24384:
        case 24409:
        case 24410:
        case 24411:
        case 24707:
        case 24800:
        case 24869:
        case 25660:
        case 25690:
        case 25691:
        case 25692:
        case 25693:
        case 25697:
        case 25700:
        case 25701:
        case 25886:
        case 25887:
        case 25990:
        case 26030:
        case 26263:
        case 27089:
        case 27094:
        case 28616:
        case 29007:
        case 29008:
        case 29029:
        case 29055:
        case 29073:
        case 30024:
        case 32112:
        case 33253:
        case 33255:
        case 33258:
        case 33260:
        case 33262:
        case 33264:
        case 33266:
        case 33269:
        case 33725:
        case 33772:
        case 34291:
        case 35270:
        case 35271:
        case 40543:
        case 40745:
        case 40768:
        case 41030:
        case 41031:
        case 42207:
        case 42308:
        case 42309:
        case 42311:
        case 42312:
        case 43154:
        case 43180:
        case 43182:
        case 43183:
        case 43706:
        case 43763:
        case 44107:
        case 44109:
        case 44110:
        case 44111:
        case 44112:
        case 44113:
        case 44114:
        case 44115:
        case 44116:
        case 44166:
        case 45019:
        case 45020:
        case 45548:
        case 45618:
        case 46683:
        case 46755:
        case 46812:
        case 46898:
        case 49472:
        case 52911:
        case 53283:
        case 53373:
        case 56439:
        case 57069:
        case 57070:
        case 57073:
        case 57084:
        case 57649:
        case 58645:
        case 58648:
        case 58886:
        case 61827:
        case 61828:
        case 61829:
        case 61830:
        case 61874:
        case 64056:
        case 64354:
        case 64355:
        case 64356:
        case 65363:
        case 65418:
        case 65419:
        case 65420:
        case 65421:
        case 65422:
        case 69560:
        case 69561:
        case 71068:
        case 71071:
        case 71073:
        case 71074:
        case 72623:
        {
            sp->setRecoveryTime(1000);
            sp->setCategoryRecoveryTime(1000);
        } break;
        default:
            break;
    }
}

void SpellMgr::applyHackFixes()
{
    //Updating spell.dbc

    sLogger.info("World : Processing {} spells...", static_cast<uint32_t>(sSpellMgr.getSpellInfoMap()->size()));

    SpellInfo* sp = nullptr;

    for (const auto& it : mSpellInfoMapStore)
    {
        // Read every SpellEntry row
        sp = sSpellMgr.getMutableSpellInfo(it.first);
        if (sp == nullptr)
            continue;

        float radius = std::max(::GetRadius(sSpellRadiusStore.lookupEntry(sp->getEffectRadiusIndex(0))), ::GetRadius(sSpellRadiusStore.lookupEntry(sp->getEffectRadiusIndex(1))));
        radius = std::max(::GetRadius(sSpellRadiusStore.lookupEntry(sp->getEffectRadiusIndex(2))), radius);
        radius = std::max(sp->getMaxRange(), radius);
        sp->custom_base_range_or_radius_sqr = radius * radius;

        sp->ai_target_type = sp->aiTargetType();

        //there are some spells that change the "damage" value of 1 effect to another : devastate = bonus first then damage
        //this is a total bullshit so remove it when spell system supports effect overwriting
        switch (sp->getId())
        {
            case 20243:     // Devastate Rank 1
            case 30016:     // Devastate Rank 2
            case 30022:     // Devastate Rank 3
            case 47497:     // Devastate Rank 4
            case 47498:     // Devastate Rank 5
            case 57795:     // Devastate
            case 60018:     // Devastate
            case 62317:     // Devastate
            case 69902:     // Devastate
            {
                uint32 temp;
                float ftemp;
                temp = sp->getEffect(1);
                sp->setEffect(sp->getEffect(2), 1);
                sp->setEffect(temp, 2);

                temp = sp->getEffectDieSides(1);
                sp->setEffectDieSides(sp->getEffectDieSides(2), 1);
                sp->setEffectDieSides(temp, 2);

                ftemp = sp->getEffectRealPointsPerLevel(1);
                sp->setEffectRealPointsPerLevel(sp->getEffectRealPointsPerLevel(2), 1);
                sp->setEffectRealPointsPerLevel(ftemp, 2);

                temp = sp->getEffectBasePoints(1);
                sp->setEffectBasePoints(sp->getEffectBasePoints(2), 1);
                sp->setEffectBasePoints(temp, 2);

                temp = sp->getEffectMechanic(1);
                sp->setEffectMechanic(sp->getEffectMechanic(2), 1);
                sp->setEffectMechanic(temp, 2);

                temp = sp->getEffectImplicitTargetA(1);
                sp->setEffectImplicitTargetA(sp->getEffectImplicitTargetA(2), 1);
                sp->setEffectImplicitTargetA(temp, 2);

                temp = sp->getEffectImplicitTargetB(1);
                sp->setEffectImplicitTargetB(sp->getEffectImplicitTargetB(2), 1);
                sp->setEffectImplicitTargetB(temp, 2);

                temp = sp->getEffectRadiusIndex(1);
                sp->setEffectRadiusIndex(sp->getEffectRadiusIndex(2), 1);
                sp->setEffectRadiusIndex(temp, 2);

                temp = sp->getEffectApplyAuraName(1);
                sp->setEffectApplyAuraName(sp->getEffectApplyAuraName(2), 1);
                sp->setEffectApplyAuraName(temp, 2);

                temp = sp->getEffectAmplitude(1);
                sp->setEffectAmplitude(sp->getEffectAmplitude(2), 1);
                sp->setEffectAmplitude(temp, 2);

                ftemp = sp->getEffectMultipleValue(1);
                sp->setEffectMultipleValue(sp->getEffectMultipleValue(2), 1);
                sp->setEffectMultipleValue(ftemp, 2);

                temp = sp->getEffectChainTarget(1);
                sp->setEffectChainTarget(sp->getEffectChainTarget(2), 1);
                sp->setEffectChainTarget(temp, 2);

                temp = sp->getEffectMiscValue(1);
                sp->setEffectMiscValue(sp->getEffectMiscValue(2), 1);
                sp->setEffectMiscValue(temp, 2);

                temp = sp->getEffectTriggerSpell(1);
                sp->setEffectTriggerSpell(sp->getEffectTriggerSpell(2), 1);
                sp->setEffectTriggerSpell(temp, 1);

                ftemp = sp->getEffectPointsPerComboPoint(1);
                sp->setEffectPointsPerComboPoint(sp->getEffectPointsPerComboPoint(2), 1);
                sp->setEffectPointsPerComboPoint(ftemp, 2);
            } break;
            default:
                break;
        }

        for (uint8 b = 0; b < 3; ++b)
        {
            if (sp->getEffectTriggerSpell(b) != 0 && sSpellMgr.getSpellInfo(sp->getEffectTriggerSpell(b)) == NULL)
            {
                // proc spell referencing non-existent spell. create a dummy spell for use w/ it.
                createDummySpell(sp->getEffectTriggerSpell(b));
            }

            if (sp->getAttributes() & ATTRIBUTES_ONLY_OUTDOORS && sp->getEffectApplyAuraName(b) == SPELL_AURA_MOUNTED)
            {
                sp->removeAttributes(ATTRIBUTES_ONLY_OUTDOORS);
            }

#if VERSION_STRING >= WotLK
            if (sp->getEffectApplyAuraName(b) == SPELL_AURA_PREVENT_RESURRECTION)
            {
                sp->addAttributes(ATTRIBUTES_NEGATIVE);
                sp->addAttributesExC(ATTRIBUTESEXC_CAN_PERSIST_AND_CASTED_WHILE_DEAD);
            }
#endif
        }

        // DankoDJ: Refactoring session 16/02/2016 new functions
        modifyEffectBasePoints(sp);
        setMissingSpellLevel(sp);
        modifyAuraInterruptFlags(sp);
        modifyRecoveryTime(sp);

        // various flight spells
        // these make vehicles and other charmed stuff fliable
        if (sp->getActiveIconID() == 2158)
            sp->addAttributes(ATTRIBUTES_PASSIVE);


        //Name includes "" overwrites
        switch (sp->getId())
        {
        case 70908:
            sp->setEffectImplicitTargetA(EFF_TARGET_DYNAMIC_OBJECT, 0);
            break;
            // Name includes "Winter's Chill"
            // Winter's Chill handled by frost school
            case 11180:     // Winter's Chill Rank 1
            case 12579:
            case 28592:     // Winter's Chill Rank 2
            case 28593:     // Winter's Chill Rank 3
            case 63094:
            {
                sp->setSchoolMask(SCHOOL_MASK_FROST);
            } break;

            // Name includes "Chain Heal"
            // more triggered spell ids are wrong. I think blizz is trying to outsmart us :S
            // Chain Heal all ranks %50 heal value (49 + 1)
            case 1064:
            case 10622:
            case 10623:
            case 14900:
            case 15799:
            case 16367:
            case 21899:
            case 23573:
            case 25422:
            case 25423:
            case 26122:
            case 30872:
            case 30873:
            case 33642:
            case 38322:
            case 38434:
            case 38435:
            case 41114:
            case 42027:
            case 42477:
            case 43527:
            case 43752:
            case 48894:
            case 54481:
            case 55437:
            case 55458:
            case 55459:
            case 55537:
            case 57232:
            case 59473:
            case 60167:
            case 61321:
            case 67226:
            case 67389:
            case 69923:
            case 70425:
            case 71120:
            case 75370:
            {
                sp->setEffectDieSides(49, 0);
            } break;

            default:
                break;
        }

        switch (sp->getId())
        {
            // SPELL_HASH_SEAL_OF_COMMAND
            case 20375:     // Seal of Command - School/dmg_type
            case 20424:
            case 29385:
            case 33127:
            case 41469:
            case 42058:
            case 57769:
            case 57770:
            case 66004:
            case 68020:
            case 68021:
            case 68022:
            case 69403:
            {
                sp->setDmgClass(SPELL_DMG_TYPE_MAGIC); //heh, crazy spell uses melee/ranged/magic dmg type for 1 spell. Now which one is correct ?
            } break;

            // SPELL_HASH_JUDGEMENT_OF_COMMAND
            case 20425:
            case 20467:
            case 29386:
            case 32778:
            case 33554:
            case 41368:
            case 41470:
            case 66005:
            case 68017:
            case 68018:
            case 68019:
            case 71551:
            {
                sp->setDmgClass(SPELL_DMG_TYPE_MAGIC);
            } break;


            // SPELL_HASH_BLESSING_OF_PROTECTION
            case 41450:
            // SPELL_HASH_DIVINE_PROTECTION
            case 498:
            case 13007:
            case 27778:
            case 27779:
            // SPELL_HASH_DIVINE_SHIELD
            case 642:
            case 13874:
            case 29382:
            case 33581:
            case 40733:
            case 41367:
            case 54322:
            case 63148:
            case 66010:
            case 67251:
            case 71550:
            {
                sp->setMechanicsType(MECHANIC_INVULNARABLE);
            } break;
        }

        // DankoDJ: This switch replaces the old NameHash overwrites
        switch (sp->getId())
        {
            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_SHIELD_OF_RIGHTEOUSNESS
            case 53600:     // Shield of Righteousness Rank 1
            case 61411:     // Shield of Righteousness Rank 2
            {
                sp->setEffect(SPELL_EFFECT_DUMMY, 0);
                sp->setEffect(SPELL_EFFECT_NULL, 1);          //hacks, handling it in Spell::SpellEffectSchoolDMG(uint32 i)
                sp->setEffect(SPELL_EFFECT_SCHOOL_DAMAGE, 2); //hack
            } break;

            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_SEALS_OF_THE_PURE
#if VERSION_STRING < Cata
            case 20224:     // Seals of the Pure Rank 1
            case 20225:     // Seals of the Pure Rank 2
            case 20330:     // Seals of the Pure Rank 3
            case 20331:     // Seals of the Pure Rank 4
            case 20332:     // Seals of the Pure Rank 5
            {
                sp->setEffectSpellClassMask(0x08000400, 0, 0);
                sp->setEffectSpellClassMask(0x20000000, 0, 1);
                sp->setEffectSpellClassMask(0x800, 1, 1);
            } break;
#endif

            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_MEND_PET
            case 136:       // Mend Pet Rank 1
            case 3111:      // Mend Pet Rank 2
            case 3661:      // Mend Pet Rank 3
            case 3662:      // Mend Pet Rank 4
            case 13542:     // Mend Pet Rank 5
            case 13543:     // Mend Pet Rank 6
            case 13544:     // Mend Pet Rank 7
            case 27046:     // Mend Pet Rank 8
            case 33976:     // Mend Pet
            case 48989:     // Mend Pet Rank 9
            case 48990:     // Mend Pet Rank 10
            {
                sp->setChannelInterruptFlags(0);
            } break;

            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_GRACE (without ranks)
            case 47930:     // Grace
            {
                sp->setRangeIndex(4);
            } break;

            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_FLAMETONGUE_ATTACK
            case 10444:     // Flametongue Attack
            case 65978:
            case 68109:
            case 68110:
            case 68111:
            {
                //sp->Effect[1] = SPELL_EFFECT_DUMMY;
                sp->addAttributesExC(ATTRIBUTESEXC_NO_DONE_BONUS);
            } break;

            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_FIRE_NOVA (ranks)
            case 1535:      //Fire Nova Rank 1
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(8349, 1);
            } break;
            case 8498:      //Fire Nova Rank 2
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(8502, 1);
            } break;
            case 8499:      //Fire Nova Rank 3
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(8503, 1);
            } break;
            case 11314:     //Fire Nova Rank 4
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(11306, 1);
            } break;
            case 11315:     //Fire Nova Rank 5
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(11307, 1);
            } break;
            case 25546:     //Fire Nova Rank 6
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(25535, 1);
            } break;
            case 25547:     //Fire Nova Rank 7
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(25537, 1);
            } break;
            case 61649:     //Fire Nova Rank 8
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(61650, 1);
            } break;
            case 61657:     //Fire Nova Rank 9
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(61654, 1);
            } break;

            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_HEX
            case 11641:     // Hex
            case 16097:     // Hex
            case 16707:     // Hex
            case 16708:     // Hex
            case 16709:     // Hex
            case 17172:     // Hex
            case 18503:     // Hex
            case 22566:     // Hex
            case 24053:     // Hex
            case 29044:     // Hex
            case 36700:     // Hex
            case 40400:     // Hex
            case 46295:     // Hex
            case 51514:     // Hex
            case 53439:     // Hex
            case 66054:     // Hex
            {
                sp->addAuraInterruptFlags(AURA_INTERRUPT_ON_UNUSED2);
            } break;

            //////////////////////////////////////////////////////////////////////////////////////////
            // SPELL_HASH_DASH
            case 1850:      // Dash
            case 9821:      // Dash
            case 33357:     // Dash
            case 36589:     // Dash
            case 43317:     // Dash
            case 44029:     // Dash
            case 44531:     // Dash
            case 61684:     // Dash
            {
                // mask for FORM_CAT(1) = 1 << (1 - 1), which is 1
                sp->setRequiredShapeShift(1);
            } break;
            case 69075: // Bone Storm (Lord Marrowgar)
            case 70834: // Bone Storm (Lord Marrowgar)
            case 70835: // Bone Storm (Lord Marrowgar)
            case 70836: // Bone Storm (Lord Marrowgar)
            case 72864: // Death Plague (Rotting Frost Giant)
            case 71160: // Plague Stench (Stinky)
            case 71161: // Plague Stench (Stinky)
            case 71123: // Decimate (Stinky & Precious)
                sp->setEffectRadiusIndex(sSpellRadiusStore.lookupEntry(12) ? sSpellRadiusStore.lookupEntry(12)->ID : 0, 0); // 100yd
                break;
            case 69055: // Saber Lash (Lord Marrowgar)
            case 70814: // Saber Lash (Lord Marrowgar)
                sp->setEffectRadiusIndex(sSpellRadiusStore.lookupEntry(14) ? sSpellRadiusStore.lookupEntry(14)->ID : 0, 0); // 8yd
                break;
            default:
                break;
        }

        // Zyres: cleanup session 09/03/2023

        createDummySpell(62388);
        createDummySpell(56817);
        createDummySpell(62330);

        switch (sp->getId())
        {
            /////////////////////////////////////////////////////////////////
            //SPELL COEFFICIENT SETTINGS END
            /////////////////////////////////////////////////////////////////

            ////////////////////////////////////////////////////////////
            // Wands
            case SPELL_RANGED_WAND:
                sp->setDmgClass(SPELL_DMG_TYPE_RANGED);
                break;

            //////////////////////////////////////////////////////
            // CLASS-SPECIFIC SPELL FIXES                       //
            //////////////////////////////////////////////////////

            // Note: when applying spell hackfixes, please follow a template

            //////////////////////////////////////////
            // WARRIOR                              //
            //////////////////////////////////////////


            ////////////////////////////////////////////////////////////
            // Arms

            // Warrior - Tactical Mastery Rank 1
            case 12295:
            // Warrior - Tactical Mastery Rank 2
            case 12676:
            // Warrior - Tactical Mastery Rank 3
            case 12677:
                sp->setRequiredShapeShift(0x00070000);
                break;

            // Warrior - Rend
            case 772:
            case 6546:
            case 6547:
            case 6548:
            case 11572:
            case 11573:
            case 11574:
            case 25208:
                sp->setMechanicsType(MECHANIC_BLEEDING);
                break;
            // Warrior - Improved Hamstring
            // Blizzard uses attackable target for this talent which won't work in our spell system...
            case 12289:
            case 12668:
            case 23695:
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 0);
                break;

            ////////////////////////////////////////////////////////////
            // Fury

            // Warrior - Slam
            case 1464:
            case 8820:
            case 11604:
            case 11605:
            case 25241:
            case 25242:
            case 47474:
            case 47475:
                sp->setEffect(SPELL_EFFECT_SCHOOL_DAMAGE, 0);
                break;

            // Warrior - Bloodthirst new version is ok but old version is wrong from now on :(
            case 23881:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1); //cast on us, it is good
                sp->setEffectTriggerSpell(23885, 1); //evil , but this is good for us :D
            } break;
            case 23892:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(23886, 1); //evil , but this is good for us :D  // DankoDJ: Is there a reason to trigger an non existing spell?
            } break;
            case 23893:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1); //
                sp->setEffectTriggerSpell(23887, 1); //evil , but this is good for us :D // DankoDJ: Is there a reason to trigger an non existing spell?
            } break;
            case 23894:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1); //
                sp->setEffectTriggerSpell(23888, 1); //evil , but this is good for us :D // DankoDJ: Is there a reason to trigger an non existing spell?
            } break;
            case 25251:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1); //aura
                sp->setEffectTriggerSpell(25252, 1); //evil , but this is good for us :D // DankoDJ: Is there a reason to trigger an non existing spell?
            } break;
            case 30335:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1); //aura
                sp->setEffectTriggerSpell(30339, 1); //evil , but this is good for us :D // DankoDJ: Is there a reason to trigger an non existing spell?
            } break;

            // Warrior - Berserker Rage
            case 18499:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_DUMMY, 0);//Forcing a dummy aura, so we can add the missing 4th effect.
                sp->setEffect(SPELL_EFFECT_NULL, 1);
                sp->setEffect(SPELL_EFFECT_NULL, 2);
            } break;

            // Warrior - Heroic Fury
            case 60970:
                sp->setEffect(SPELL_EFFECT_DUMMY, 0);
                break;
            ////////////////////////////////////////////////////////////
            // Protection

            // Intervene  Ranger: stop attack
            case 3411:
                sp->addAttributes(ATTRIBUTES_STOP_ATTACK);
                break;
            //////////////////////////////////////////
            // PALADIN                              //
            //////////////////////////////////////////

            //Paladin - Hammer of the Righteous
            case 53595:
                sp->setSpeed(0);    //without, no damage is done
                break;

            //Paladin - Divine Storm
            case 53385:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectRadiusIndex(43, 0); //16 yards
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(54172, 1);
                sp->setProcChance(100);
                sp->setMaxTargets(4);
            } break;

            //Paladin - Judgements of the Wise
            case 31930:
            case 54180:
            {
                sp->setSpellFamilyName(0);
                sp->setSpellFamilyFlags(0, 0);
                sp->setSpellFamilyFlags(0, 1);
                sp->setSpellFamilyFlags(0, 2);
            } break;

            //Paladin - Avenging Wrath marker - Is forced debuff
            case 61987:
            //Paladin - Forbearance - Is forced debuff
            case 25771:
                sp->setAttributes(ATTRIBUTES_IGNORE_INVULNERABILITY);
                break;

            //Divine Protection
            case 498:
            //Divine Shield
            case 642:
            //Hand of Protection Rank 1
            case 1022:
            //Hand of Protection Rank 2
            case 5599:
            //Hand of Protection Rank 3
            case 10278:
                sp->setTargetAuraSpellNot(25771);
                break;

            //Paladin - Hammer of Justice - Interrupt effect
            case 853:
            case 5588:
            case 5589:
            case 10308:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(32747, 1);
            } break;

            //////////////////////////////////////////
            // HUNTER                               //
            //////////////////////////////////////////

            // Insert hunter spell fixes here

            // Hunter - Spirit Bond
            case 19578:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(19579, 0);
            } break;

            case 20895:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(24529, 0);
            } break;

            case 19579:
            case 24529:
            {
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 1); //we should do the same for player too as we did for pet
                sp->setEffectApplyAuraName(sp->getEffectApplyAuraName(0), 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 1);
                sp->setEffectBasePoints(sp->getEffectBasePoints(0), 1);
                sp->setEffectAmplitude(sp->getEffectAmplitude(0), 1);
                sp->setEffectDieSides(sp->getEffectDieSides(0), 1);
            } break;

            // Hunter - Ferocious Inspiration
            case 34455:
            case 34459:
            case 34460:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
                sp->setEffectTriggerSpell(34456, 0);
                sp->setEffect(SPELL_EFFECT_NULL, 1); //remove this
            } break;

            // Hunter - Focused Fire
            case 35029:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(35060, 0);
            } break;

            case 35030:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(35061, 0);
            } break;

            // Hunter - Thrill of the Hunt
            case 34497:
            case 34498:
            case 34499:
            {
                sp->setProcChance(sp->calculateEffectValue(0));
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(34720, 0);
            } break;

            //Hunter - Frenzy
            case 19621:
            case 19622:
            case 19623:
            case 19624:
            case 19625:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(19615, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
                sp->setProcChance(sp->getEffectBasePoints(0));
            } break;

            // Feed pet
            case 6991:
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 0);
                break;

            //////////////////////////////////////////
            // ROGUE                                //
            //////////////////////////////////////////

            // Garrote - this is used?
            case 37066:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_SINGLE_ENEMY, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_SINGLE_ENEMY, 1);
            } break;

            //rogue - Vanish : Second Trigger Spell
            case 18461:
                sp->addAttributesEx(ATTRIBUTESEX_NOT_BREAK_STEALTH);
                break;

            //rogue - Shadowstep
            case 36563:
                sp->setEffectMiscValue(SPELLMOD_ALL_EFFECTS, 2);
                sp->addAttributesEx(ATTRIBUTESEX_NOT_BREAK_STEALTH);
                break;

            // Still related to shadowstep - prevent the trigger spells from breaking stealth.
            case 44373:
            case 36554:
                sp->addAttributesEx(ATTRIBUTESEX_NOT_BREAK_STEALTH);
                break;

            //garrot
            case 703:
            case 8631:
            case 8632:
            case 8633:
            case 11289:
            case 11290:
            case 26839:
            case 26884:

            //rupture
            case 1943:
            case 8639:
            case 8640:
            case 11273:
            case 11274:
            case 11275:
            case 26867:
                sp->setMechanicsType(MECHANIC_BLEEDING);
                break;

            //Rogue - Killing Spree Stealth fix
            case 51690:
                sp->addAttributesEx(ATTRIBUTESEX_NOT_BREAK_STEALTH);
                break;

            // Fan of knives
            case 51723:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_ALL_ENEMY_IN_AREA, 0);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 0);
            } break;

            // Rogue - Master of Subtlety
            case 31665:
                sp->addAttributesEx(ATTRIBUTESEX_NOT_BREAK_STEALTH);
                break;

            //////////////////////////////////////////
            // PRIEST                               //
            //////////////////////////////////////////

            // Prayer of mending
            case 41635:
            case 48110:
            case 48111:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_DUMMY, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_SINGLE_FRIEND, 0);
            } break;

            case 33110:
                sp->setEffectImplicitTargetA(EFF_TARGET_SINGLE_FRIEND, 0);
                break;

            // Body and soul - fix duration of cleanse poison
            case 64134:
                sp->setDurationIndex(29);
                break;

            // Spirit of Redemption - required spells can be casted while dead
            case 27795:   // This is casted by shape shift
            case 27792:   // This is casted by Apply Aura: Spirit of Redemption
                sp->addAttributesExC(ATTRIBUTESEXC_CAN_PERSIST_AND_CASTED_WHILE_DEAD);
                break;

            //Priest - Wand Specialization
            case 14524:
            case 14525:
            case 14526:
            case 14527:
            case 14528:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_ADD_PCT_MODIFIER, 0);
                sp->setEffectMiscValue(SPELLMOD_ALL_EFFECTS, 0);
            } break;

            //Priest - Inspiration proc spell
            case 14893:
            case 15357:
            case 15359:
                sp->setRangeIndex(4);
                break;

            // priest - Reflective Shield
            case 33201:
            case 33202:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(33619, 0); //!! WRONG spell, we will make direct dmg here
            } break;

            // Weakened Soul - Is debuff
            case 6788:
                sp->setAttributes(ATTRIBUTES_IGNORE_INVULNERABILITY);
                break;

            // Penance
            case 47540:
            case 53005:
            case 53006:
            case 53007:
            {
                sp->setDurationIndex(566);
                sp->setChannelInterruptFlags(0);
            } break;

            // Penance triggered healing spells have wrong targets.
            case 47750:
            case 52983:
            case 52984:
            case 52985:
                sp->setEffectImplicitTargetA(EFF_TARGET_SINGLE_FRIEND, 0);
                break;

            //////////////////////////////////////////
            // SHAMAN                               //
            //////////////////////////////////////////

            // Shamanistic Rage
            case 30824:
            {
                if (SpellInfo const* parentsp = getMutableSpellInfo(30823))
                    sp->setEffectBasePoints(parentsp->getEffectBasePoints(0), 0);
            } break;

            //summon only 1 elemental totem
            case 2894:
                sp->setEffectImplicitTargetA(EFF_TARGET_TOTEM_FIRE, 0); //remove this targeting. it is enough to get 1 target
                break;

            //summon only 1 elemental totem
            case 2062:
                sp->setEffectImplicitTargetA(EFF_TARGET_TOTEM_EARTH, 0); //remove this targeting. it is enough to get 1 target
                break;

            //Bloodlust
            case 2825:
                sp->setCasterAuraSpellNot(57724); //sated debuff
                break;

            // Sated - is debuff
            case 57724:
                sp->setAttributes(ATTRIBUTES_IGNORE_INVULNERABILITY);
                break;

            //Heroism
            case 32182:
                sp->setCasterAuraSpellNot(57723); //sated debuff
                break;

            // Sated - is debuff
            case 57723:
                sp->setAttributes(ATTRIBUTES_IGNORE_INVULNERABILITY);
                break;

            // Purge
            case 370:
            case 8012:
            case 27626:
            case 33625:
                sp->setDispelType(DISPEL_MAGIC);
                break;

            //Shaman - Shamanistic Focus
            // needs to be fixed (doesn't need to proc, it now just reduces mana cost always by %)
            case 43338:
                sp->setEffectTriggerSpell(43339, 0);
                break;

            case 43339:
                sp->setEffectMiscValue(SPELLMOD_COST, 0);
                break;

            //shaman - Improved Chain Heal
            case 30873:
            case 30872:
                sp->setEffectDieSides(0, 0);
                break;

            //shaman - Improved Weapon Totems
            case 29193:
            case 29192:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_ADD_PCT_MODIFIER, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_ADD_PCT_MODIFIER, 1);
                sp->setEffectMiscValue(SPELLMOD_ALL_EFFECTS, 0);
                sp->setEffectMiscValue(SPELLMOD_ALL_EFFECTS, 1);
            } break;

            // Shaman - Improved Fire Totems
            case 16544:
            case 16086:
                sp->setEffectMiscValue(SPELLMOD_DURATION, 0);
                break;

            //shaman - Elemental Weapons
            case 29080:
            case 29079:
            case 16266:
            {
                sp->setEffectMiscValue(SPELLMOD_DAMAGE_DONE, 1);
                sp->setEffectMiscValue(SPELLMOD_DAMAGE_DONE, 2);
            } break;

            //  Unleashed Rage - LordLeeCH
            case 30802:
            case 30808:
            case 30809:
                sp->setEffect(SPELL_EFFECT_APPLY_GROUP_AREA_AURA, 0);
                break;

            // Ancestral healing proc spell
            case 16177:
            case 16236:
            case 16237:
                sp->setRangeIndex(4);
                break;

            case 20608:   //Reincarnation
            {
                for (uint8 i = 0; i < 8; ++i)
                {
                    if (sp->getReagent(i))
                    {
                        sp->setReagent(0, i);
                        sp->setReagentCount(0, i);
                    }
                }
            } break;

            //////////////////////////////////////////
            // MAGE                                 //
            //////////////////////////////////////////

            // Brain Freeze rank 1
            case 44546:
            // Brain Freeze rank 2
            case 44548:
            // Brain Freeze rank 3
            case 44549:
            // Fingers of Frost rank 1
            case 44543:
            // Fingers of Frost rank 2
            case 44545:
                sp->setEffectApplyAuraName(SPELL_AURA_DUMMY, 0);
                break;

            //Mage - Spell Power
            case 35578:
            case 35581:
            {
                sp->setEffectMiscValue(SPELLMOD_CRITICAL_DAMAGE, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_ADD_PCT_MODIFIER, 0);
            } break;

            //Mage - Elemental Precision
            case 29438:
            case 29439:
            case 29440:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_ADD_PCT_MODIFIER, 0);
                sp->setEffectMiscValue(SPELLMOD_COST, 0);
            } break;

            //Mage - Arcane Blast
            case 30451:
            case 42894:
            case 42896:
            case 42897:
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 1);
                break;

            //mage : Empowered Arcane Missiles
            case 31579:
            case 31582:
            case 31583:
                sp->setEffectBasePoints(5 * (sp->calculateEffectValue(0)), 0);
                break;

            //Arcane Potency procs
            case 57529:
            case 57531:
            {
                sp->setProcFlags(0);
                sp->setAuraInterruptFlags(0);
            } break;

            //mage - Combustion
            case 11129:
            {
                sp->setEffect(SPELL_EFFECT_NULL, 0);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 1);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(28682, 1);
                sp->setProcChance(0);
            } break;

            // mage - Conjure Refreshment Table
            case 43985:
                sp->setEffectImplicitTargetA(EFF_TARGET_DYNAMIC_OBJECT, 0);
                break;

            // Hypothermia - forced debuff
            case 41425:
                sp->setAttributes(ATTRIBUTES_IGNORE_INVULNERABILITY);
                break;

            // Mage - Permafrost Rank 1
            case 11175:
            // Mage - Permafrost Rank 2
            case 12569:
            // Mage - Permafrost Rank 3
            case 12571:
                sp->setEffectMiscValue(SPELLMOD_ALL_EFFECTS, 1);
                break;

            //////////////////////////////////////////
            // WARLOCK                              //
            //////////////////////////////////////////

            //Dummy for Demonic Circle
            case 48018:
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 1);
                break;

            case 62388:
            {
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_DUMMY, 0);
            } break;

            //megai2: Immolation Aura
            case 50589:
                sp->setChannelInterruptFlags(0); // Remove channeling behaviour.
                break;

#if VERSION_STRING < Cata
            //megai2: Everlasting Affliction
            case 47205:
            case 47204:
            case 47203:
            case 47202:
            case 47201:
            {
                sp->setEffectSpellClassMask(0x111, 1, 0);
                sp->setEffectSpellClassMask(0, 1, 1);
            } break;
#endif

            // Demonic Knowledge
            case 35691:
            case 35692:
            case 35693:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_MOD_DAMAGE_DONE, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 0);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 1);
                sp->setEffectApplyAuraName(SPELL_AURA_MOD_DAMAGE_DONE, 1);
                sp->setEffectBasePoints(sp->getEffectBasePoints(0), 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 1);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 2);
                sp->setEffectTriggerSpell(35696, 2);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 2);
            } break;

            case 35696:
            {
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0); //making this only for the visible effect
                sp->setEffectApplyAuraName(SPELL_AURA_DUMMY, 0); //no effect here
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
            } break;

            //warlock: Empowered Corruption
            case 32381:
            case 32382:
            case 32383:
                sp->setEffectBasePoints(sp->getEffectBasePoints(0) * 6, 0);
                break;

            //warlock - Demonic Tactics
            case 30242:
            case 30245:
            case 30246:
            case 30247:
            case 30248:
            {
                sp->setEffect(SPELL_EFFECT_NULL, 0); //disable this. This is just blizz crap. Pure proof that they suck :P
                sp->setEffectImplicitTargetB(EFF_TARGET_PET, 1);
                sp->setEffectImplicitTargetB(EFF_TARGET_PET, 2);
            } break;

            //warlock - Demonic Resilience
            case 30319:
            case 30320:
            case 30321:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 1);
            } break;

            //warlock - Improved Imp
            case 18694:
            case 18695:
            case 18696:

            //warlock - Demonic Brutality
            case 18705:
            case 18706:
            case 18707:
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
                break;

            //warlock - Improved Succubus
            case 18754:
            case 18755:
            case 18756:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 1);
            } break;

            //warlock - Fel Vitality
            case 18731:
            case 18743:
            case 18744:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_MOD_PERCENT_STAT, 0);
                sp->setEffectMiscValue(3, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
            } break;

            //warlock - Unholy Power
            case 18769:
            case 18770:
            case 18771:
            case 18772:
            case 18773:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_ADD_PCT_MODIFIER, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
                //this is required since blizz uses spells for melee attacks while we use fixed functions
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 1);
                sp->setEffectApplyAuraName(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 1);
                sp->setEffectMiscValue(SCHOOL_NORMAL, 1);
                sp->setEffectBasePoints(sp->getEffectBasePoints(0), 1);
            } break;

            //warlock - Master Demonologist - 25 spells here
            case 23785:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(23784, 0);
            } break;
            case 23822:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(23830, 0);
            } break;
            case 23823:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(23831, 0);
            } break;
            case 23824:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(23832, 0);
            } break;
            case 23825:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(35708, 0);
            } break;

            //and the rest
            case 23784:
            case 23830:
            case 23831:
            case 23832:
            case 35708:
                sp->setEffectImplicitTargetA(EFF_TARGET_PET, 0);
                break;

            case 23759:
            case 23760:
            case 23761:
            case 23762:
            case 23826:
            case 23827:
            case 23828:
            case 23829:

            case 23833:
            case 23834:
            case 23835:
            case 23836:
            case 23837:
            case 23838:
            case 23839:
            case 23840:
            case 23841:
            case 23842:
            case 23843:
            case 23844:
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                break;

            case 35702:
            case 35703:
            case 35704:
            case 35705:
            case 35706:
            {
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                sp->setEffect(SPELL_EFFECT_NULL, 1); //hacks, we are handling this in another way
            } break;

            //warlock - Improved Drain Soul
            case 18213:
            case 18372:
            {
                sp->setProcChance(100);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(18371, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 0);
                sp->setEffect(SPELL_EFFECT_NULL, 2); //remove this effect
            } break;

            //Warlock Chaos bolt
            case 50796:
            case 59170:
            case 59171:
            case 59172:
                sp->addAttributes(ATTRIBUTES_IGNORE_INVULNERABILITY);
                break;

            case 6201:
            case 6202:
            case 5699:
            case 11729:
            case 11730:
            case 27230:
            case 47871:
            case 47878:
                sp->setReagent(0, 1);
                break;

            //////////////////////////////////////////
            // DRUID                                //
            //////////////////////////////////////////

            ////////////////////////////////////////////////////////////
            // Balance

            // Druid - Force of Nature
            case 33831:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 0); //some land under target is used that gathers multiple targets ...
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 1);
            } break;

            ////////////////////////////////////////////////////////////
            //    Feral Combat

            // Druid - Bash - Interrupt effect
            case 5211:
            case 6798:
            case 8983:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(32747, 1);
            } break;

            //Druid - Feral Swiftness
            case 17002:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(24867, 1);
            } break;
            case 24866:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(24864, 1);
            } break;

            // Druid - Maim
            case 22570:
            case 49802:
                sp->setAuraInterruptFlags(AURA_INTERRUPT_ON_UNUSED2);
                break;

            case 20719: //feline grace
                sp->setEffect(SPELL_EFFECT_NULL, 0);
                break;

            // Druid - Frenzied Regeneration
            case 22842:
            {
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_PERIODIC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(22845, 0);
            }break;

            // Druid - Primal Fury (talent)
            case 37116:
            case 37117:
                sp->setRequiredShapeShift(0);
                break;

            // Druid - Predatory Strikes
            case 16972:
            case 16974:
            case 16975:
            {
                uint32_t mm = decimalToMask(FORM_BEAR) | decimalToMask(FORM_DIREBEAR) | decimalToMask(FORM_MOONKIN) | decimalToMask(FORM_CAT);
                sp->setRequiredShapeShift(mm);
            } break;

            ////////////////////////////////////////////////////////////
            // Restoration

            // Druid - Natural Shapeshifter
            case 16833:
            case 16834:
            case 16835:
                sp->setDurationIndex(0);
                break;

            //////////////////////////////////////////
            // DEATH KNIGHT                         //
            //////////////////////////////////////////

            // Unholy Aura - Ranks 1
            case 50391:
            // Unholy Aura - Ranks 2
            case 50392:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS, 0);
                sp->setEffect(SPELL_EFFECT_APPLY_GROUP_AREA_AURA, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(50392, 1);
                sp->setEffect(SPELL_EFFECT_APPLY_GROUP_AREA_AURA, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 1);
            } break;

#if VERSION_STRING >= TBC
            // Empower Rune Weapon
            case 47568:
            {
                sp->setEffect(SPELL_EFFECT_ACTIVATE_RUNES, 2);
                sp->setEffectBasePoints(1, 2);
                sp->setEffectMiscValue(RUNE_UNHOLY, 2);
            } break;
#endif

            // DEATH AND DECAY
            case 49937:
            case 49936:
            case 49938:
            case 43265:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_PERIODIC_DAMAGE, 0);
                sp->setEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA, 0);
            } break;

            // Vengeance
            case 93099:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(76691, 0);
            } break;

            // Path of Frost
            case 3714:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_WATER_WALK, 0);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
            } break;

            // Rune Strike
            case 56815:
                sp->addAttributes(ATTRIBUTES_CANT_BE_DPB);
                break;

            case 56817:
            {
                sp->setDurationIndex(28);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_DUMMY, 0);
            } break;

            //Frost Strike
            case 49143:
            case 51416:
            case 51417:
            case 51418:
            case 51419:
            case 55268:
                sp->setAttributes(ATTRIBUTES_CANT_BE_DPB);
                break;

            //////////////////////////////////////////
            // ITEMS                                //
            //////////////////////////////////////////

            case 61177: // Northrend Inscription Research
            case 61288: // Minor Inscription Research
            case 60893: // Northrend Alchemy Research
            {
                sp->setEffect(SPELL_EFFECT_NULL, 1);
                sp->setEffectBasePoints(0, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 1);
                sp->setEffectDieSides(0, 1);
            } break;

#if VERSION_STRING < Cata

            case 46097: // Brutal Totem of Survival
            case 43860: // Totem of Survival
            case 43861: // Merciless Totem of Survival
            case 43862: // Vengeful Totem of Survival
            {
                sp->setEffectSpellClassMask(0x00100000 | 0x10000000 | 0x80000000, 0, 0);
                sp->setEffectSpellClassMask(0x08000000, 0, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 1);
            } break;

            case 60564: // Savage Gladiator's Totem of Survival
            {
                sp->setEffectSpellClassMask(0x00100000 | 0x10000000 | 0x80000000, 0, 0);
                sp->setEffectSpellClassMask(0x08000000, 0, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 1);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(60565, 1); // Savage Magic
            } break;

            case 60571: // Hateful Gladiator's Totem of Survival
            {
                sp->setEffectSpellClassMask(0x00100000 | 0x10000000 | 0x80000000, 0, 0);
                sp->setEffectSpellClassMask(0x08000000, 0, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 1);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(60566, 1); // Hateful Magic
            } break;

            case 60572: // Deadly Gladiator's Totem of Survival
            {
                sp->setEffectSpellClassMask(0x00100000 | 0x10000000 | 0x80000000, 0, 0);
                sp->setEffectSpellClassMask(0x08000000, 0, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 1);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(60567, 1); // Deadly Magic
            } break;

            case 60567: // Deadly Magic
                sp->setEffectImplicitTargetA(EFF_TARGET_SELF, 1);
                break;

            case 46098: // Brutal Totem of Third WInd
            {
                sp->setEffectSpellClassMask(0x00000080, 0, 0);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(46099, 1); // Brutal Gladiator's Totem of the Third Wind
            } break;

            case 34138: // Totem of the Third Wind
            {
                sp->setEffectSpellClassMask(0x00000080, 0, 0);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(34132, 1); // Gladiator's Totem of the Third Wind
            } break;

            case 42370: // Merciless Totem of the Third WInd
            {
                sp->setEffectSpellClassMask(0x00000080, 0, 0);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(42371, 1); // Merciless Gladiator's Totem of the Third Wind
            } break;

            case 43728: // Vengeful Totem of Third WInd
            {
                sp->setEffectSpellClassMask(0x00000080, 0, 0);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(43729, 1); // Vengeful Gladiator's Totem of the Third Wind
            } break;

#endif

            //Compact Harvest Reaper
            case 4078:
                sp->setDurationIndex(6);
                break;

            //Graccu's Mince Meat Fruitcake
            case 25990:
                sp->setEffectAmplitude(1000, 1);
                break;

            //Extract Gas
            case 30427:
                sp->setEffect(SPELL_EFFECT_DUMMY, 0);
                break;

            //Primal Instinct - Idol of Terror proc
            case 43738:
                sp->custom_self_cast_only = true;
                break;

            //Thunderfury
            case 21992:
                sp->setEffectImplicitTargetA(EFF_TARGET_ALL_ENEMIES_AROUND_CASTER, 2); // cebernic: for enemies not self
                break;

            // todo: write spell script for this
            // Sigil of the Unfaltering Knight
            /*case 62147:
                sp->custom_proc_interval = 45000;
            break;*/

            // Deadly Aggression - triggered by Deadly Gladiator's Relic/Idol/Libram/Totem
            case 60549:
            // Furious Gladiator's Libram of Fortitude - triggered by LK Arena 4 Gladiator's Relic/Idol/Libram/Totem
            case 60551:
            // Relentless Aggression - triggered by LK Arena 5 Gladiator's Relic/Idol/Libram/Totem
            case 60553:
            // Savage Aggression - triggered by Savage Gladiator's Relic/Idol/Libram/Totem
            case 60544:
                // effect 1 and 2 are the same... dunno why
                sp->setEffect(SPELL_EFFECT_NULL, 1);
                break;

            // todo: write spell script for this
            // Sigil of Haunted Dreams
            /*case 60826:
                sp->custom_proc_interval = 45000;
                break;*/

            //Totem of the Third Wind - bad range
            case 34132:
            case 42371:
            case 43729:
            case 46099:
                sp->setRangeIndex(5);
                break;

            // Eye of Acherus, our phase shift mode messes up the control :/
            case 51852:
                sp->setEffect(SPELL_EFFECT_NULL, 0);
                break;

            //Ashtongue Talisman of Equilibrium
            case 40442:
            {
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(40452, 0);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 1);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(40445, 1);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 2);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 2);
                sp->setProcChance(25);
                sp->setEffectTriggerSpell(40446, 2);
                sp->setMaxstack(1);
            } break;

            //Ashtongue Talisman of Acumen
            case 40438:
            {
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setProcChance(10);
                sp->setEffectTriggerSpell(40441, 0);
                sp->setMaxstack(1);
                sp->setEffect(SPELL_EFFECT_APPLY_AURA, 1);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(40440, 1);
            } break;

            // Drums of war targets surrounding party members instead of us
            case 35475:
            // Drums of Battle targets surrounding party members instead of us
            case 35476:
            // Drums of Restoration targets surrounding party members instead of us
            case 35478:
            // Drums of Speed targets surrounding party members instead of us
            case 35477:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_ALL_PARTY, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_ALL_PARTY, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 2);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 0);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 1);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 2);
                sp->setRequiredShapeShift(0);
            } break;

            // Drums of Panic targets surrounding creatures instead of us
            case 35474:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_ALL_ENEMIES_AROUND_CASTER, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_ALL_ENEMIES_AROUND_CASTER, 1);
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 2);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 0);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 1);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 2);
                sp->setRequiredShapeShift(0);
            } break;

            //Purify helboar meat
            case 29200:
            {
                sp->setReagent(0, 1);
                sp->setReagentCount(0, 1);
            } break;

            //Thorium Grenade
            case 19769:
            //M73 Frag Grenade
            case 13808:
            //Iron Grenade
            case 4068:
            //Frost Grenade
            case 39965:
            //Adamantine Grenade
            case 30217:
                sp->removeInterruptFlags(CAST_INTERRUPT_ON_MOVEMENT);
                break;

            ///////////////////////////////////////////////////////////////
            // Trinket Fixes        Please keep nice and clean :)
            ///////////////////////////////////////////////////////////////

            //Figurine - Shadowsong Panther
            case 46784:        //    http://www.wowhead.com/?item=35702
                sp->addAttributesEx(ATTRIBUTESEX_NOT_BREAK_STEALTH);
                break;

            // Infernal Protection
            case 36488:            //    http://www.wowhead.com/?spell=36488
                sp->setEffectImplicitTargetA(EFF_TARGET_SINGLE_FRIEND, 0);
                break;

            //Fury of the Five Flights
            case 60313:
                sp->setMaxstack(20);
                break;

            //Pendant of the Violet Eye
            case 35095:
                sp->custom_self_cast_only = true;
                break;

            //////////////////////////////////////////
            // BOSSES                               //
            //////////////////////////////////////////

            // Blood Nova (Deathbringer Saurfang) - limit range to 100 yards
            case 72378:
            case 73058:
            // Boiling Blood (Deathbringer Saurfang) - limit range to 100 yards
            case 72385:
            case 72441:
            case 72442:
            case 72443:
                sp->setRangeIndex(6);
                break;

            // Bone Storm (Lord Marrowgar)
            case 69075:
                sp->setEffectImplicitTargetA(SPELL_TARGET_AREA, 0);
                break;

            // Major Domo - Magic Reflection
            case 20619:
            // Major Domo - Damage Shield
            case 21075:
            {
                for (uint8 i = 0; i < 3; ++i)
                {
                    if (sp->getEffectImplicitTargetA(i) > 0)
                        sp->setEffectImplicitTargetA(EFF_TARGET_ALL_FRIENDLY_IN_AREA, i);
                    if (sp->getEffectImplicitTargetB(i) > 0)
                        sp->setEffectImplicitTargetB(EFF_TARGET_ALL_FRIENDLY_IN_AREA, i);
                }
            } break;

            // Dark Glare
            case 26029:
                sp->cone_width = 15.0f; // 15 degree cone
                break;

            // Drain Power (Malacrass) // bugged - the charges fade even when refreshed with new ones. This makes them everlasting.
            case 44131:
            case 44132:
                sp->setDurationIndex(21);
                break;

            // Zul'jin spell, proc from Creeping Paralysis
            case 43437:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 0);
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 1);
            } break;

            //Bloodboil
            case 42005:
                sp->setMaxTargets(5);
                break;

            //Doom
            case 31347:
                sp->setMaxTargets(1);
                break;

            //Shadow of Death
            case 40251:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_PERIODIC_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(0, 0);
            } break;

            case 9036:
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 1);
                sp->setEffectTriggerSpell(20584, 1);
            } break;

            case 24379:   //bg Restoration
                sp->setEffectTriggerSpell(23493, 0);
                break;

            case 23493:   //bg Restoration
                sp->setEffectTriggerSpell(24379, 0);
                break;

            case 5246:    // why self?
            {
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(20511, 0); // cebernic: this just real spell
                sp->setEffectImplicitTargetA(EFF_TARGET_NONE, 0);
            } break;

            // Noggenfogger elixir - reduce size effect
            case 16595:
            {
                sp->setEffectApplyAuraName(SPELL_AURA_MOD_SCALE, 0);
                sp->setEffectBasePoints(-50, 0);
                sp->setMaxstack(1);
            } break;

            case 46584:
            {
                sp->setEffect(SPELL_EFFECT_DUMMY, 0);
                sp->setEffect(SPELL_EFFECT_NULL, 1);
                sp->setEffect(SPELL_EFFECT_NULL, 2);
            } break;

            //Other Librams
            //Libram of Saints Departed and Libram of Zeal
            case 34263:
            //Libram of Avengement
            case 34260:
            //Libram of Mending
            case 43742:
            {
                sp->custom_self_cast_only = true;
                sp->setProcChance(100);
            } break;

            // Recently Bandaged - is debuff
            case 11196:
                sp->setAttributes(ATTRIBUTES_IGNORE_INVULNERABILITY);
                break;

            case 44856:        // Bash'ir Phasing Device
                sp->setAuraInterruptFlags(AURA_INTERRUPT_ON_LEAVE_AREA);
                break;

            case 24574:        // Zandalarian Hero Badge 24590 24575
            {
                sp->setEffect(SPELL_EFFECT_TRIGGER_SPELL, 0);
                sp->setEffectTriggerSpell(24590, 0);
                sp->setEffectApplyAuraName(SPELL_AURA_PROC_TRIGGER_SPELL, 0);
            } break;

            //Tempfix for Stone Statues
            case 32253:
            case 32787:
            case 32788:
            case 32790:
            case 32791:
                sp->setDurationIndex(64);
                break;

            //////////////////////////////////////////////////////
            // GAME-OBJECT SPELL FIXES                          //
            //////////////////////////////////////////////////////

            // Blessing of Zim'Torga
            case 51729:
            // Blessing of Zim'Abwa
            case 51265:
            // Blessing of Zim'Rhuk
            case 52051:
                sp->setEffectImplicitTargetA(EFF_TARGET_SCRIPTED_OR_SINGLE_TARGET, 0);
                break;

            // Ritual of Summoning summons a GameObject that triggers an inexistant spell.
            // This will copy an existant Summon Player spell used for another Ritual Of Summoning
            // to the one taught by Warlock trainers.
            case 7720:
            {
                const uint32_t ritOfSummId = 62330;
                SpellInfo* ritOfSumm = getMutableSpellInfo(ritOfSummId);
                if (ritOfSumm != NULL)
                {
                    memcpy(ritOfSumm, sp, sizeof(SpellInfo));
                    ritOfSumm->setId(ritOfSummId);
                }
            } break;

            //Persistent Shield
            case 26467:
            {
                sp->setEffectTriggerSpell(26470, 0);
                sp->addAttributes(ATTRIBUTES_NO_VISUAL_AURA | ATTRIBUTES_PASSIVE);
                sp->setDurationIndex(0);
            } break;

            //Gravity Bomb
            case 63024:
            {
                sp->setEffectBasePoints(0, 0);
                sp->setEffect(SPELL_EFFECT_NULL, 1);
                sp->setEffect(SPELL_EFFECT_NULL, 2);
                sp->setTargetAuraState(0);
                sp->setCasterAuraSpell(0);
                sp->setCasterAuraState(0);
                sp->setCasterAuraStateNot(0);
                sp->setTargetAuraStateNot(0);
                sp->setTargetAuraSpell(0);
                sp->setCasterAuraSpellNot(0);
                sp->setTargetAuraSpellNot(0);
                sp->addAttributes(ATTRIBUTES_NEGATIVE);
            } break;

            // War Stomp
            case 20549:
            {
                sp->setEffectImplicitTargetA(EFF_TARGET_ALL_ENEMY_IN_AREA, 0);
                sp->setEffectImplicitTargetB(EFF_TARGET_NONE, 0);
            } break;

            default:
                break;
        }
    }
    // END OF LOOP
}
